E5 - Fourier interpolation

This step performs Fourier interpolation on a tiff image or video, to generate new pixels between physical pixels and yield a higher resolution.

Fourier interpolation shares similar core ideas as the Fourier SOFI (fSOFI) algorithm. However, our method can yield a faster processing pipeline. More specifically, Fourier interpolation is a two-step transformation matrix operation. The Fourier transformation matrix was constructed with the original matrix size, and the inverse Fourier transformation matrix encodes the extra interpolation position coordinates. This way we create a mathematical equivalence of zero-padding fourier interpolation (fSOFI), but avoid actual zero-padding in the Fourier space in order to reduce the physical memory occupation for the operation. In this way, the input image/video is 'projected' onto a finer grid with reduced pixel sizes.

In this notebook, we demonstrate how to carry out Fourier interpolation on a tiff image or video using pysofi. The image/video generated can then be tranferred to SOFI processing. This method is adopted from this MATLAB version.

1. Load data into PysofiData object.

The input data can be a singel image or a video (tiff image stacks) from simulations or fluorescence imaging experiements. In this notebook, we use data from Hela cells transfected with Dronpa-C12 (fluorescent protein) fused to β-Actin. Live cells were imaged with 30 ms frame integration and 200 frames in total.

The input data ('Block10.tif' video) is first loaded into the PysofiData object.

In [1]:
import sys
sys.path.append('..')
import numpy as np
import matplotlib.pyplot as plt
import tifffile as tiff
from functions import pysofi, finterp
from functions import visualization as v
%matplotlib inline

# load data into PysofiData object
filepath = '../sampledata'
filename = 'Block10.tif'
d = pysofi.PysofiData(filepath, filename)
Loading BokehJS ...

2. Fourier interpolation.

d.finterp_tiffstack is a method of the PysofiData object that carries out Fourier interpolation on the video directly. Note that this step might consume large memory or time, depending on the tiff file (dimensions, frame number) and the number of new pixels generated.

We can pass a few parameters to finterp_tiffstack:

  • interp_num_lst: a list of interpolation factors (integers). THe meaning of the interpolation factor is explained below. Based on Nyquist sampling theorem, we recommend to set the interpolation factor at least two times the highest order of moment-/cumulant reconstructions. For instance, if we will generate a fourth-order moment-reconstructed image, we set interp_num_lst = [8], and the new pixel size $d_{new} = \frac{d_{ori}}{8}$.
  • frames: frames of the video for interpolation.
  • save_option: whether to save the interpolated images into tiff files. Seperate tiff files will be produced for individual interpolation factors in interp_num_lst.
  • return_option: whether to return the interpolated image series as 3d arrays. This is helpful for checking interpolated images and plotting them directly. We recommend to save the interpolated image stack as tiff files instead of returning them if dimensions and number of frames are large.

The user can carry out interpolation first and save the interpolated image / video for following pysofi steps, or skip this step and set finterp = True in moments or cumulants reconstructions. We recommend to set the interpolation factor two times the reconstruction order number based on Nyquist sampling theorem. However, if your computation ability could not support too big interpolation factor, it is practical to use a smaller factor.

In [2]:
d.finterp_tiffstack(interp_num_lst=[2,4], frames=[0,100], save_option=True, return_option=False)
Calculating interpolation factor = 2...
[==============================] 100.0%

If the user select save_option = True, the generated file will be saved in the same folder as the origianl file. The user can also choose to just interpolate and return a single frame.

In [4]:
finterp_im = d.finterp_tiffstack(interp_num_lst=[4], frames=[10,11], save_option=False, return_option=True)
original_im = d.get_frame(10)
v.bokeh_visualization_mult([original_im, finterp_im[0][0]], ['Original Image', 'Interpolated Image (factor=4)'])
Calculating interpolation factor = 4...
[==============================] 100.0%

Loading BokehJS ...

As we can see, the interpolated image reserved all the details of the original image, and increase the dimensions based on the interpolation factor. The interpolation factor describes the number of pixels added between two adjacent pixels. The user should note that the dimensions of the interpolated image is not an integer fold of the original dimensions. Suppose the original dimensions are xdim and ydim respectively. After Fourier interpolation, the dimensions will be $(xdim-1)*f + 1$ and $(ydim-1)*f + 1$.

3. Fourier interpolation with finterp.

Another way to just test Fourier interpolation on an array (one image) is to direcly pass the array and a list of interpolation factors to finterp.fourier_interp_array. This step can be added at any stage of the analysis piipeline, and can be especially helpful before the SOFI 2.0 analysis.

In [6]:
im = tiff.imread(filepath + '/' + filename, key=15)
finterp_im2 = finterp.fourier_interp_array(im, [10])

plt.figure(figsize = (8,8))
plt.imshow(finterp_im2[0], cmap='pink')
Out[6]:
<matplotlib.image.AxesImage at 0x19eb27fd400>